package com.gxgeek.redis.application.lock;

import com.gxgeek.redis.application.redistool.JedisExecutor;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;

/**
 * Created by gx on 2017/7/7.
 */
@Slf4j// 通过watch   事务(multi)实现
public class RedisKill {

    //模拟秒杀 系统
    public static void main(String[] args) {
        JedisExecutor.execute(jedis -> jedis.set("mykey","1000000"));
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

@Slf4j
class MyThread extends Thread {

    @Override
    public void run() {
        while (true) {
            System.out.println(Thread.currentThread().getName());
            try {
                int stock = Integer.parseInt(JedisExecutor.execute(jedis->jedis.get("mykey")));
                if (stock > 0) {
                    JedisExecutor.executeNR(jedis->{
                        jedis.watch("mykey");
                        Transaction transaction = jedis.multi();
                        transaction.set("mykey", String.valueOf(stock - 1));
                        List<Object> result = transaction.exec();
                        if (result == null || result.isEmpty()) {
                            System.out.println("Transaction error...");// 可能是watch-key被外部修改，或者是数据操作被驳回
                        }else {
                            System.out.println(result);
                        }
                    });
                } else {
                    System.out.println("库存为0");
                    break;
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }
        }
    }

}
